package com.huawang.mdesign.model.service.util.uaf;

import com.huawang.core.definition.mof.UMLDefinitionConstants;
import org.apache.logging.log4j.util.Strings;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * UAF交换模型的工具类
 */
public class ExchangeUtils {

    private ExchangeUtils() {
    }

    /**
     * 根据传输对象类型来获得其对应的ExchangeKind
     */
    @NotNull
    public static String getExchangeKindByConveyedType(String exchangeStereotype, Set<String> conveyedTypes) {
        if (UMLDefinitionConstants.UAF_OperationalExchange.equals(exchangeStereotype)) {
            return getOperationalExchangeConveyedType(conveyedTypes);
        } else if (UMLDefinitionConstants.UAF_ResourceExchange.equals(exchangeStereotype)) {
            return getResourceExchangeConveyedType(conveyedTypes);
        } else if (UMLDefinitionConstants.UAF_ServiceExchange.equals(exchangeStereotype)) {
            return getServiceExchangeConveyedType(conveyedTypes);
        } else if (UMLDefinitionConstants.UAF_StrategicExchange.equals(exchangeStereotype)) {
            return Strings.EMPTY;
        } else {
            return Strings.EMPTY;
        }
    }

    /**
     * ServiceExchange
     *
     */
    @NotNull
    private static String getServiceExchangeConveyedType(Set<String> conveyedTypes) {
        if (conveyedTypes.contains(UMLDefinitionConstants.UAF_OperationalInformation) || conveyedTypes.contains(UMLDefinitionConstants.UAF_ServiceSignal)) {
            return UMLDefinitionConstants.UAF_ServiceExchangeKind_InformationExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_ResourcePerformer)) {
            return UMLDefinitionConstants.UAF_ServiceExchangeKind_MaterielExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_NaturalResource)) {
            return UMLDefinitionConstants.UAF_ServiceExchangeKind_EnergyExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_OrganizationalResource)) {
            return UMLDefinitionConstants.UAF_ServiceExchangeKind_OrganizationalExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_ResourceArchitecture)) {
            return UMLDefinitionConstants.UAF_ServiceExchangeKind_ConfigurationExchange;
        } else {
            return Strings.EMPTY;
        }
    }

    /**
     * ResourceExchange
     *
     */
    @NotNull
    private static String getResourceExchangeConveyedType(Set<String> conveyedTypes) {
        if (conveyedTypes.contains(UMLDefinitionConstants.UAF_ResourceInformation) || conveyedTypes.contains(UMLDefinitionConstants.UAF_ResourceSignal)) {
            return UMLDefinitionConstants.UAF_ResourceExchangeKind_ResourceCommunication;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_ResourcePerformer)) {
            return UMLDefinitionConstants.UAF_ResourceExchangeKind_ResourceMovement;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_NaturalResource)) {
            return UMLDefinitionConstants.UAF_ResourceExchangeKind_ResourceEnergyFlow;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_GeoPoliticalExtentType)) {
            return UMLDefinitionConstants.UAF_ResourceExchangeKind_GeoPoliticalExtentExchange;
        } else {
            return Strings.EMPTY;
        }
    }

    /**
     * OperationalExchange
     *
     */
    @NotNull
    private static String getOperationalExchangeConveyedType(Set<String> conveyedTypes) {
        if (conveyedTypes.contains(UMLDefinitionConstants.UAF_OperationalInformation) || conveyedTypes.contains(UMLDefinitionConstants.UAF_OperationalSignal)) {
            return UMLDefinitionConstants.UAF_OperationalExchangeKind_InformationExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_OperationalPerformer)) {
            return UMLDefinitionConstants.UAF_OperationalExchangeKind_MaterielExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_NaturalResource)) {
            return UMLDefinitionConstants.UAF_OperationalExchangeKind_EnergyExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_OrganizationalResource)) {
            return UMLDefinitionConstants.UAF_OperationalExchangeKind_OrganizationalExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_ResourceArchitecture)) {
            return UMLDefinitionConstants.UAF_OperationalExchangeKind_ConfigurationExchange;
        } else if (conveyedTypes.contains(UMLDefinitionConstants.UAF_GeoPoliticalExtentType)) {
            return UMLDefinitionConstants.UAF_OperationalExchangeKind_GeoPoliticalExtentExchange;
        } else {
            return Strings.EMPTY;
        }
    }

    /**
     * 根据转换类型，获得其conveyed的类型
     *
     */
    @NotNull
    public static List<String> getExchangeConveyedType(String exchangeKind) {
        List<String> types = new ArrayList<>(2);
        if (Objects.nonNull(exchangeKind)) {
            switch (exchangeKind) {
                //UMLDefinitionConstants.UAF_OperationalExchange
                case UMLDefinitionConstants.UAF_OperationalExchangeKind_InformationExchange:
                    types.add(UMLDefinitionConstants.UAF_OperationalInformation);
                    types.add(UMLDefinitionConstants.UAF_OperationalSignal);
                    break;
                case UMLDefinitionConstants.UAF_OperationalExchangeKind_MaterielExchange:
                    types.add(UMLDefinitionConstants.UAF_ResourceArtifact);
                    break;
                case UMLDefinitionConstants.UAF_OperationalExchangeKind_EnergyExchange:
                case UMLDefinitionConstants.UAF_ResourceExchangeKind_ResourceEnergyFlow:
                case UMLDefinitionConstants.UAF_ServiceExchangeKind_EnergyExchange:
                    types.add(UMLDefinitionConstants.UAF_NaturalResource);
                    break;
                case UMLDefinitionConstants.UAF_OperationalExchangeKind_OrganizationalExchange:
                case UMLDefinitionConstants.UAF_ServiceExchangeKind_OrganizationalExchange:
                    types.add(UMLDefinitionConstants.UAF_OrganizationalResource);
                    break;
                case UMLDefinitionConstants.UAF_OperationalExchangeKind_ConfigurationExchange:
                case UMLDefinitionConstants.UAF_ServiceExchangeKind_ConfigurationExchange:
                    types.add(UMLDefinitionConstants.UAF_ResourceArchitecture);
                    break;
                case UMLDefinitionConstants.UAF_OperationalExchangeKind_GeoPoliticalExtentExchange:
                case UMLDefinitionConstants.UAF_ResourceExchangeKind_GeoPoliticalExtentExchange:
                    types.add(UMLDefinitionConstants.UAF_GeoPoliticalExtentType);
                    break;

                //UMLDefinitionConstants.UAF_ResourceExchange
                case UMLDefinitionConstants.UAF_ResourceExchangeKind_ResourceCommunication:
                    types.add(UMLDefinitionConstants.UAF_ResourceInformation);
                    types.add(UMLDefinitionConstants.UAF_ResourceSignal);
                    break;
                case UMLDefinitionConstants.UAF_ResourceExchangeKind_ResourceMovement:
                case UMLDefinitionConstants.UAF_ServiceExchangeKind_MaterielExchange:
                    types.add(UMLDefinitionConstants.UAF_ResourcePerformer);
                    break;

                //UMLDefinitionConstants.UAF_ServiceExchange
                case UMLDefinitionConstants.UAF_ServiceExchangeKind_InformationExchange:
                    types.add(UMLDefinitionConstants.UAF_OperationalInformation);
                    types.add(UMLDefinitionConstants.UAF_ServiceSignal);
                    break;
                default:
                    break;
            }
        } else {
            //UMLDefinitionConstants.UAF_StrategicExchange
            return Stream.of(UMLDefinitionConstants.UAF_StrategicInformation, UMLDefinitionConstants.UAF_ResourcePerformer, UMLDefinitionConstants.UAF_GeoPoliticalExtentType).collect(Collectors.toList());
        }
        return types;
    }
}

